'use strict';

const RSVP = require('rsvp');

const app = require('../app');

const {
  getFileDir,
  isScratchPaper
} = require('../utils');

const {
  checkLoading,
  setPath
} = require('./helpers');

const get = require('./ajax/get');
const Server = require("./index");

const loadDataAndCode = (dir, explanation) => {
  return RSVP.hash({
    data: get(`${dir}data.js`),
    code: get(`${dir}code.js`),
    template: get(`${dir}template.txt`),
    explanation: explanation
  });
};

const isTemplate = (dir, data, code, template) => {
  dir = dir.replace(/[\/#?]+$/, '');
  const lastPart = dir.split('/').pop().toLowerCase();
  let pattern1 = "template";
  let pattern2 = "模板";
  if(lastPart.indexOf(pattern1) !== -1 || lastPart.indexOf(pattern2) !== -1) {
    return true;
  }
  return false;
}

const setLang = (dir) => {
  dir = dir.replace(/[\/#?]+$/, '');
  const lastPart = dir.split('/').pop().toLowerCase();
  // 定义语言标识及其变体（不区分大小写）
  const languagePatterns = {
    'c_cpp': ['cpp', 'cplusplus', 'c++', 'cxx'],
    'java': ['java', 'jdk'],
    'python': ['python', 'py', 'python3', 'python2'],
    'javascript': ['javascript', 'js', 'ecmascript', 'es6'],
    'typescript': ['typescript', 'ts'],
    'golang': ['go', 'golang'],
    'rust': ['rust', 'rs'],
    'php': ['php'],
    'csharp': ['csharp', 'c#', 'cs'],
  };

  // 检查是否匹配任何语言模式
  for (const [lang, patterns] of Object.entries(languagePatterns)) {
    for (const pattern of patterns) {
      if (lastPart.indexOf(pattern) !== -1) {
        app.getEditor().setMode(lang, app.getEditor().getTemplateEditor());
        return;
      }
    }
  }

  app.getEditor().setMode('javascript', app.getEditor().getTemplateEditor());
}

const loadFileAndUpdateContent = (dir, explanation) => {
  app.getEditor().clearContent();

  return loadDataAndCode(dir, explanation).then((content) => {
    app.updateCachedFile(dir, content);
    const {
      data, code, template
    } = content;
    if(isTemplate(dir, data, code, template)) {
      $('.data_container').hide();
      $('.code_container').hide();
      $('.template_container').show();
      $("#btn_run").prop("disabled", true);
      $("#btn_run").addClass("disabled");
      if($("#btn_prev").prop("disabled") === false) {
        $("#btn_prev").prop("disabled", true);
        $("#btn_prev").addClass("disabled");
      }
      if($("#btn_next").prop("disabled") === false) {
        $("#btn_next").prop("disabled", true);
        $("#btn_next").addClass("disabled");
      }
      if($("#btn_pause").prop("disabled") === false) {
        $("#btn_pause").prop("disabled", true);
        $("#btn_pause").addClass("disabled");
      }
      app.getEditor().setCode('');
      app.getEditor().setData('');
      setLang(dir);
      app.getEditor().setTemplate(template);
    } else {
      $('.data_container').show();
      $('.code_container').show();
      $('.template_container').hide();
      $("#btn_run").prop("disabled", false);
      $("#btn_run").removeClass("disabled");
      if($("#btn_prev").prop("disabled") === true) {
        $("#btn_prev").prop("disabled", false);
        $("#btn_prev").removeClass("disabled");
      }
      if($("#btn_next").prop("disabled") === true) {
        $("#btn_next").prop("disabled", false);
        $("#btn_next").removeClass("disabled");
      }
      if($("#btn_pause").prop("disabled") === true) {
        $("#btn_pause").prop("disabled", false);
        $("#btn_pause").removeClass("disabled");
      }
      app.getEditor().setCode(code);
      app.getEditor().setData(data);
      app.getEditor().setTemplate('');
    }
  });
};

const cachedContentExists = (cachedFile) => {
  return cachedFile &&
    cachedFile.data !== undefined &&
    cachedFile.code !== undefined;
};

module.exports = (category, algorithm, file, explanation) => {
  return new RSVP.Promise((resolve, reject) => {
    if (checkLoading()) {
      reject();
    } else {
      if (isScratchPaper(category)) {
        setPath(category, app.getLoadedScratch());

        let dir = getFileDir('scratch', '', file);
        const cachedFile = app.getCachedFile(dir);

        $('#explanation').attr('contenteditable', 'true')
          .off('blur') // 避免重复绑定
          .on('blur', function () {
            const newExplain = $(this).html().trim();

            if(cachedContentExists(cachedFile)) {
              cachedFile['explanation'] = newExplain;
              app.updateCachedFile(dir, cachedFile);
            } else {
              loadDataAndCode(dir, newExplain).then((content) => {
                app.updateCachedFile(dir, content);
              });
            }
          });
        if(cachedFile === undefined) {
          $('#explanation').html(explanation);
        } else {
          $('#explanation').html(cachedFile['explanation'] === undefined ? explanation : cachedFile['explanation']);
        }
      } else {
        setPath(category, algorithm, file);
        $('#explanation').html(explanation);
      }

      let dir = getFileDir(category, algorithm, file);
      app.setLastFileUsed(dir);
      const cachedFile = app.getCachedFile(dir);

      if (cachedContentExists(cachedFile)) {
        const {
          data, code, template
        } = cachedFile;
        if(isTemplate(dir, data, code, template)) {
          $('.data_container').hide();
          $('.code_container').hide();
          $('.template_container').show();
          $("#btn_run").prop("disabled", true);
          $("#btn_run").addClass("disabled");
          if($("#btn_prev").prop("disabled") === false) {
            $("#btn_prev").prop("disabled", true);
            $("#btn_prev").addClass("disabled");
          }
          if($("#btn_next").prop("disabled") === false) {
            $("#btn_next").prop("disabled", true);
            $("#btn_next").addClass("disabled");
          }
          if($("#btn_pause").prop("disabled") === false) {
            $("#btn_pause").prop("disabled", true);
            $("#btn_pause").addClass("disabled");
          }
          app.getEditor().setCode('');
          app.getEditor().setData('');
          setLang(dir);
          app.getEditor().setTemplate(template);
        } else {
          $('.data_container').show();
          $('.code_container').show();
          $('.template_container').hide();
          $("#btn_run").prop("disabled", false);
          $("#btn_run").removeClass("disabled");
          if($("#btn_prev").prop("disabled") === true) {
            $("#btn_prev").prop("disabled", false);
            $("#btn_prev").removeClass("disabled");
          }
          if($("#btn_next").prop("disabled") === true) {
            $("#btn_next").prop("disabled", false);
            $("#btn_next").removeClass("disabled");
          }
          if($("#btn_pause").prop("disabled") === true) {
            $("#btn_pause").prop("disabled", false);
            $("#btn_pause").removeClass("disabled");
          }
          app.getEditor().setCode(code);
          app.getEditor().setData(data);
          app.getEditor().setTemplate('');
        }
        resolve();
      } else {
        loadFileAndUpdateContent(dir, explanation).then(resolve, reject);
      }
    }
  });
};
